package org.veloxbot.api.wrappers;

import org.veloxbot.api.methods.Game;

import org.veloxbot.api.utils.ColorUtil;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;

import java.util.List;
import java.util.ArrayList;

/**
 * @author Caleb
 */
public class DTM {

	private final DTMRoot root;
	private final DTMBranch[] branches;

	/**
	 * Constructs a DTM (Deformable Template Model) of a root, and branches.
	 *
	 * @param root     The main point in which the branches are relativly based upon.
	 * @param branches Points branched off the root.
	 */
	public DTM(final DTMRoot root, final DTMBranch... branches) {
		this.root = root;
		this.branches = branches;
	}

	/**
	 * Gets the root of the DTM.
	 *
	 * @return The root of the DTM.
	 */
	public DTMRoot getRoot() {
		return root;
	}

	/**
	 * Gets the branches of the DTM.
	 *
	 * @return The branches of the DTM.
	 */
	public DTMBranch[] getBranches() {
		return branches;
	}

	/**
	 * Gets the first found DTM match.
	 *
	 * @param bounds The bounds in which to search in.
	 * @return The point in which the first match is located at.
	 */
	public Point getFirst(final Rectangle bounds) {
		for (int x = bounds.x; x < bounds.x + bounds.width; x++) {
			for (int y = bounds.y; y < bounds.y + bounds.height; y++) {
				if (isAt(x, y)) {
					return new Point(x, y);
				}
			}
		}
		return null;
	}

	/**
	 * Gets an array of all matched points.
	 *
	 * @param bounds The bounds in which to search in.
	 * @return An rray of all matched points.
	 */
	public Point[] getAll(final Rectangle bounds) {
		final List<Point> points = new ArrayList<Point>();
		for (int x = bounds.x; x < bounds.x + bounds.width; x++) {
			for (int y = bounds.y; y < bounds.y + bounds.height; y++) {
				if (isAt(x, y)) {
					points.add(new Point(x, y));
				}
			}
		}
		return points.toArray(new Point[points.size()]);
	}

	private boolean isAt(final int x, final int y) {
		if (ColorUtil.dist(root.getColor(), Game.getColorAt(x, y)) <= root.getTolerance()) {
			for (final DTMBranch branch : branches) {
				final Color branchPointColor = Game.getColorAt(x + branch.getOffsetX(), y + branch.getOffsetY());
				if (ColorUtil.dist(branch.getColor(), branchPointColor) > branch.getTolerance()) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
}
